package gui;

import arena.Arena;
import behavior.AStarBehavior;
import behavior.Behavior;
import behavior.BehaviorLoader;
import threads.QueueClient;
import graphics.Imagery;
import graphics.Point;
import java.awt.Color;
import threads.VideoThread;
import java.awt.Dimension;
import java.awt.event.FocusEvent;
import robot.Robot;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.DefaultCaret;
import robot.DBComm;
import robot.VirtualRobot;

/**
 * The main GUI component.  Holds all GUI elements and calls upon methods
 * in other classes for operation.
 * @author Gabriel Loewen, James Weston, Jackie O'Quinn
 */
public class Client extends javax.swing.JPanel {

    /**
     * The delay in milliseconds of a virtual robot
     */
    public static int robotDelay = 100;
    /**
     * The width of the virtual arena
     */
    public static int virtualWidth = 10;
    /**
     * The height of the virtual arena
     */
    public static int virtualHeight = 10;
    /**
     * The file chooser used for selecting an image for the imagery system
     */
    private final JFileChooser fc = new JFileChooser();
    /**
     * Reference to the filename used for imagery
     */
    private String nodePatternFile;
    /**
     * Reference to an Imagery object
     */
    private Imagery img = new Imagery();
    /**
     * Booleab value representing whether or not an image is loaded
     */
    private boolean nodePatternLoaded = false;
    /**
     * Reference to an arena used as a temporary space for node imagery
     */
    public Arena newArena;
    /**
     * Hashmap representing groups of robots based on their String name (i.e. "Group1" points to a List of robots in Group 1)
     */
    private HashMap<String, ArrayList> groupMap = new HashMap<String, ArrayList>();
    /**
     * A reference to the queueing system used for physical robot interraction
     */
    public QueueClient queueClient;
    /**
     * A reference to an arraylist of all possible behavior plugins
     */
    public ArrayList<Behavior> behaviorList;
    /**
     * A reference to the BehaviorLoader object in charge of loading all behavior plugins
     */
    private BehaviorLoader bl;

    /** 
     * Creates new form
     */
    public Client() {
        initComponents();
        bl = new BehaviorLoader(new File("Behaviors"));
        refreshVirtualList();
        refreshPhysicalList();
        txtOutput.setCaret(new DefaultCaret() {

            public void focusGained(FocusEvent e) {
                super.focusGained(e);
                setVisible(true);
            }
        });
        updateOutput("\nInitializing system: Complete.\nLoading behaviors: Complete.\nReady.\n\nWelcome to the DRL Client Application v1.0\n" +
                "-----------------------------------\n");
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jspSplitPane = new javax.swing.JSplitPane();
        pnlLeftPanel = new javax.swing.JPanel();
        jTabPane = new javax.swing.JTabbedPane();
        jScrollPhysical = new javax.swing.JScrollPane();
        pnlPhysical = new javax.swing.JPanel();
        pnlPhysicalRobotList = new javax.swing.JPanel();
        spanePhysicalRobotList = new javax.swing.JScrollPane();
        lstPhysicalRobots = new javax.swing.JList();
        pnlPhysicalBehaviors = new javax.swing.JPanel();
        spanePhysicalBehaviors = new javax.swing.JScrollPane();
        lstPhysicalBehaviors = new javax.swing.JList();
        tbarPhysical = new javax.swing.JToolBar();
        btnLoadBehaviorPhysical = new javax.swing.JButton();
        btnRefreshPhysicalList = new javax.swing.JButton();
        pnlDatabase = new javax.swing.JPanel();
        txtAddress = new javax.swing.JTextField();
        lblAddress = new javax.swing.JLabel();
        txtDatabase = new javax.swing.JTextField();
        lblDatabase = new javax.swing.JLabel();
        txtUsername = new javax.swing.JTextField();
        lblUsername = new javax.swing.JLabel();
        txtPassword = new javax.swing.JPasswordField();
        lblPassword = new javax.swing.JLabel();
        btnConnect = new javax.swing.JButton();
        jScrollVirtual = new javax.swing.JScrollPane();
        pnlVirtual = new javax.swing.JPanel();
        pnlVirtualRobotList = new javax.swing.JPanel();
        spaneVirtualRobotList = new javax.swing.JScrollPane();
        lstVirtualRobots = new javax.swing.JList();
        pnlVirtualBehaviors = new javax.swing.JPanel();
        spaneVirtualBehaviors = new javax.swing.JScrollPane();
        lstVirtualBehaviors = new javax.swing.JList();
        tbarVirtual = new javax.swing.JToolBar();
        btnLoadBehaviorVirtual = new javax.swing.JButton();
        btnRefreshVirtualList = new javax.swing.JButton();
        jScrollSetup = new javax.swing.JScrollPane();
        pnlSetup = new javax.swing.JPanel();
        pnlRobotDelay = new javax.swing.JPanel();
        sldRobotDelay = new javax.swing.JSlider();
        pnlImagery = new javax.swing.JPanel();
        btnResetNode = new javax.swing.JButton();
        btnLoadPattern = new javax.swing.JButton();
        lblNodePattern = new javax.swing.JLabel();
        pnlRobotManager = new javax.swing.JPanel();
        scrRobotManager = new javax.swing.JScrollPane();
        tblRobotManager = new javax.swing.JTable();
        btnAdd = new javax.swing.JButton();
        btnRemove = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        pnlGridSize = new javax.swing.JPanel();
        sldArenaSize = new javax.swing.JSlider();
        lblSize = new javax.swing.JLabel();
        pnlGridOptions = new javax.swing.JPanel();
        jscrollGridOptions = new javax.swing.JScrollPane();
        tblGridOptions = new javax.swing.JTable();
        pnlPhysicalSettings = new javax.swing.JPanel();
        btnResetPhysicalNodes = new javax.swing.JButton();
        pnlCommand = new javax.swing.JPanel();
        txtInput = new javax.swing.JTextField();
        spaneOutput = new javax.swing.JScrollPane();
        txtOutput = new javax.swing.JTextArea();
        btnCommandSubmit = new javax.swing.JButton();
        mainToolbar = new javax.swing.JToolBar();
        btnFile = new javax.swing.JButton();
        btnAbout = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        jbtID = new javax.swing.JLabel();

        jspSplitPane.setBorder(null);
        jspSplitPane.setDividerLocation(400);

        jScrollPhysical.setBorder(null);

        pnlPhysical.setPreferredSize(new java.awt.Dimension(100, 580));

        pnlPhysicalRobotList.setBorder(javax.swing.BorderFactory.createTitledBorder("Robot List"));
        pnlPhysicalRobotList.setPreferredSize(new java.awt.Dimension(355, 163));

        spanePhysicalRobotList.setViewportView(lstPhysicalRobots);

        javax.swing.GroupLayout pnlPhysicalRobotListLayout = new javax.swing.GroupLayout(pnlPhysicalRobotList);
        pnlPhysicalRobotList.setLayout(pnlPhysicalRobotListLayout);
        pnlPhysicalRobotListLayout.setHorizontalGroup(
            pnlPhysicalRobotListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalRobotListLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spanePhysicalRobotList, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE)
                .addContainerGap())
        );
        pnlPhysicalRobotListLayout.setVerticalGroup(
            pnlPhysicalRobotListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalRobotListLayout.createSequentialGroup()
                .addComponent(spanePhysicalRobotList, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                .addContainerGap())
        );

        pnlPhysicalBehaviors.setBorder(javax.swing.BorderFactory.createTitledBorder("Behavior List"));

        spanePhysicalBehaviors.setViewportView(lstPhysicalBehaviors);

        tbarPhysical.setFloatable(false);
        tbarPhysical.setRollover(true);

        btnLoadBehaviorPhysical.setText("Load");
        btnLoadBehaviorPhysical.setFocusable(false);
        btnLoadBehaviorPhysical.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnLoadBehaviorPhysical.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnLoadBehaviorPhysical.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadBehaviorPhysicalActionPerformed(evt);
            }
        });
        tbarPhysical.add(btnLoadBehaviorPhysical);

        btnRefreshPhysicalList.setText("Refresh List");
        btnRefreshPhysicalList.setFocusable(false);
        btnRefreshPhysicalList.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnRefreshPhysicalList.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnRefreshPhysicalList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRefreshPhysicalListActionPerformed(evt);
            }
        });
        tbarPhysical.add(btnRefreshPhysicalList);

        javax.swing.GroupLayout pnlPhysicalBehaviorsLayout = new javax.swing.GroupLayout(pnlPhysicalBehaviors);
        pnlPhysicalBehaviors.setLayout(pnlPhysicalBehaviorsLayout);
        pnlPhysicalBehaviorsLayout.setHorizontalGroup(
            pnlPhysicalBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlPhysicalBehaviorsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlPhysicalBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(tbarPhysical, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE)
                    .addComponent(spanePhysicalBehaviors, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlPhysicalBehaviorsLayout.setVerticalGroup(
            pnlPhysicalBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalBehaviorsLayout.createSequentialGroup()
                .addComponent(spanePhysicalBehaviors, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tbarPhysical, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pnlDatabase.setBorder(javax.swing.BorderFactory.createTitledBorder("Database Settings"));

        txtAddress.setText("aasudrl1.db.6601164.hostedresource.com");

        lblAddress.setText("Address:");

        txtDatabase.setText("aasudrl1");

        lblDatabase.setText("Database:");

        txtUsername.setText("aasudrl1");
        txtUsername.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtUsernameActionPerformed(evt);
            }
        });

        lblUsername.setText("Username:");

        txtPassword.setText("Csci1301");

        lblPassword.setText("Password:");

        btnConnect.setText("Connect");
        btnConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConnectActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlDatabaseLayout = new javax.swing.GroupLayout(pnlDatabase);
        pnlDatabase.setLayout(pnlDatabaseLayout);
        pnlDatabaseLayout.setHorizontalGroup(
            pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDatabaseLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlDatabaseLayout.createSequentialGroup()
                        .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(lblAddress)
                            .addComponent(lblDatabase)
                            .addComponent(lblUsername)
                            .addComponent(lblPassword))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE)
                            .addComponent(txtUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE)
                            .addComponent(txtAddress, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE)
                            .addComponent(txtDatabase, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE)))
                    .addComponent(btnConnect, javax.swing.GroupLayout.Alignment.TRAILING))
                .addContainerGap())
        );
        pnlDatabaseLayout.setVerticalGroup(
            pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDatabaseLayout.createSequentialGroup()
                .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblAddress))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblDatabase)
                    .addComponent(txtDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblUsername))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblPassword))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnConnect)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout pnlPhysicalLayout = new javax.swing.GroupLayout(pnlPhysical);
        pnlPhysical.setLayout(pnlPhysicalLayout);
        pnlPhysicalLayout.setHorizontalGroup(
            pnlPhysicalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlPhysicalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlPhysicalBehaviors, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlDatabase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlPhysicalRobotList, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlPhysicalLayout.setVerticalGroup(
            pnlPhysicalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlPhysicalRobotList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlPhysicalBehaviors, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(79, Short.MAX_VALUE))
        );

        jScrollPhysical.setViewportView(pnlPhysical);

        jTabPane.addTab("Physical", jScrollPhysical);

        jScrollVirtual.setBorder(null);

        pnlVirtual.setPreferredSize(new java.awt.Dimension(100, 360));

        pnlVirtualRobotList.setBorder(javax.swing.BorderFactory.createTitledBorder("Robot List"));

        spaneVirtualRobotList.setViewportView(lstVirtualRobots);

        javax.swing.GroupLayout pnlVirtualRobotListLayout = new javax.swing.GroupLayout(pnlVirtualRobotList);
        pnlVirtualRobotList.setLayout(pnlVirtualRobotListLayout);
        pnlVirtualRobotListLayout.setHorizontalGroup(
            pnlVirtualRobotListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlVirtualRobotListLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spaneVirtualRobotList, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE)
                .addContainerGap())
        );
        pnlVirtualRobotListLayout.setVerticalGroup(
            pnlVirtualRobotListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlVirtualRobotListLayout.createSequentialGroup()
                .addComponent(spaneVirtualRobotList, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                .addContainerGap())
        );

        pnlVirtualBehaviors.setBorder(javax.swing.BorderFactory.createTitledBorder("Behavior List"));

        lstVirtualBehaviors.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        spaneVirtualBehaviors.setViewportView(lstVirtualBehaviors);

        tbarVirtual.setFloatable(false);
        tbarVirtual.setRollover(true);

        btnLoadBehaviorVirtual.setText("Load");
        btnLoadBehaviorVirtual.setFocusable(false);
        btnLoadBehaviorVirtual.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnLoadBehaviorVirtual.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnLoadBehaviorVirtual.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadBehaviorVirtualActionPerformed(evt);
            }
        });
        tbarVirtual.add(btnLoadBehaviorVirtual);

        btnRefreshVirtualList.setText("Refresh List");
        btnRefreshVirtualList.setFocusable(false);
        btnRefreshVirtualList.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnRefreshVirtualList.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnRefreshVirtualList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRefreshVirtualListActionPerformed(evt);
            }
        });
        tbarVirtual.add(btnRefreshVirtualList);

        javax.swing.GroupLayout pnlVirtualBehaviorsLayout = new javax.swing.GroupLayout(pnlVirtualBehaviors);
        pnlVirtualBehaviors.setLayout(pnlVirtualBehaviorsLayout);
        pnlVirtualBehaviorsLayout.setHorizontalGroup(
            pnlVirtualBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlVirtualBehaviorsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlVirtualBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(tbarVirtual, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE)
                    .addComponent(spaneVirtualBehaviors, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlVirtualBehaviorsLayout.setVerticalGroup(
            pnlVirtualBehaviorsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlVirtualBehaviorsLayout.createSequentialGroup()
                .addComponent(spaneVirtualBehaviors, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tbarVirtual, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        javax.swing.GroupLayout pnlVirtualLayout = new javax.swing.GroupLayout(pnlVirtual);
        pnlVirtual.setLayout(pnlVirtualLayout);
        pnlVirtualLayout.setHorizontalGroup(
            pnlVirtualLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlVirtualLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlVirtualLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(pnlVirtualBehaviors, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlVirtualRobotList, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlVirtualLayout.setVerticalGroup(
            pnlVirtualLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlVirtualLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlVirtualRobotList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlVirtualBehaviors, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(284, Short.MAX_VALUE))
        );

        jScrollVirtual.setViewportView(pnlVirtual);

        jTabPane.addTab("Virtual", jScrollVirtual);

        jScrollSetup.setBorder(null);
        jScrollSetup.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollSetup.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        pnlSetup.setMinimumSize(new java.awt.Dimension(500, 0));
        pnlSetup.setPreferredSize(new java.awt.Dimension(100, 690));

        pnlRobotDelay.setBorder(javax.swing.BorderFactory.createTitledBorder("Robot Movement Delay (100 ms)"));

        sldRobotDelay.setMajorTickSpacing(100);
        sldRobotDelay.setMaximum(1000);
        sldRobotDelay.setPaintLabels(true);
        sldRobotDelay.setPaintTicks(true);
        sldRobotDelay.setValue(100);
        sldRobotDelay.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldRobotDelayStateChanged(evt);
            }
        });

        javax.swing.GroupLayout pnlRobotDelayLayout = new javax.swing.GroupLayout(pnlRobotDelay);
        pnlRobotDelay.setLayout(pnlRobotDelayLayout);
        pnlRobotDelayLayout.setHorizontalGroup(
            pnlRobotDelayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(sldRobotDelay, javax.swing.GroupLayout.DEFAULT_SIZE, 334, Short.MAX_VALUE)
        );
        pnlRobotDelayLayout.setVerticalGroup(
            pnlRobotDelayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlRobotDelayLayout.createSequentialGroup()
                .addComponent(sldRobotDelay, javax.swing.GroupLayout.DEFAULT_SIZE, 65, Short.MAX_VALUE)
                .addContainerGap())
        );

        pnlImagery.setBorder(javax.swing.BorderFactory.createTitledBorder("Virtual Arena Imagery"));

        btnResetNode.setText("Reset");
        btnResetNode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResetNodeActionPerformed(evt);
            }
        });

        btnLoadPattern.setText("Load Node Pattern");
        btnLoadPattern.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadPatternActionPerformed(evt);
            }
        });

        lblNodePattern.setText("Node Pattern Not Loaded");

        javax.swing.GroupLayout pnlImageryLayout = new javax.swing.GroupLayout(pnlImagery);
        pnlImagery.setLayout(pnlImageryLayout);
        pnlImageryLayout.setHorizontalGroup(
            pnlImageryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlImageryLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlImageryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlImageryLayout.createSequentialGroup()
                        .addGap(6, 6, 6)
                        .addComponent(lblNodePattern, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE))
                    .addGroup(pnlImageryLayout.createSequentialGroup()
                        .addComponent(btnLoadPattern, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnResetNode)))
                .addContainerGap())
        );
        pnlImageryLayout.setVerticalGroup(
            pnlImageryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlImageryLayout.createSequentialGroup()
                .addGroup(pnlImageryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnResetNode)
                    .addComponent(btnLoadPattern))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblNodePattern)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlRobotManager.setBorder(javax.swing.BorderFactory.createTitledBorder("Grid/Robot Management"));

        tblRobotManager.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Robot Name", "X", "Y", "Heading"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, true, true, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tblRobotManager.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                tblRobotManagerKeyPressed(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                tblRobotManagerKeyTyped(evt);
            }
        });
        scrRobotManager.setViewportView(tblRobotManager);

        btnAdd.setText("Add");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });

        btnRemove.setText("Remove");
        btnRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoveActionPerformed(evt);
            }
        });

        btnSave.setText("Save");
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });

        pnlGridSize.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

        sldArenaSize.setMajorTickSpacing(100);
        sldArenaSize.setMaximum(1000);
        sldArenaSize.setMinimum(5);
        sldArenaSize.setMinorTickSpacing(50);
        sldArenaSize.setPaintLabels(true);
        sldArenaSize.setPaintTicks(true);
        sldArenaSize.setValue(10);
        sldArenaSize.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                sldArenaSizeMouseReleased(evt);
            }
        });
        sldArenaSize.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldArenaSizeStateChanged(evt);
            }
        });
        sldArenaSize.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                sldArenaSizePropertyChange(evt);
            }
        });

        lblSize.setText("Current Size: 10x10");

        javax.swing.GroupLayout pnlGridSizeLayout = new javax.swing.GroupLayout(pnlGridSize);
        pnlGridSize.setLayout(pnlGridSizeLayout);
        pnlGridSizeLayout.setHorizontalGroup(
            pnlGridSizeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGridSizeLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlGridSizeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlGridSizeLayout.createSequentialGroup()
                        .addComponent(sldArenaSize, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(pnlGridSizeLayout.createSequentialGroup()
                        .addComponent(lblSize, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
                        .addGap(34, 34, 34))))
        );
        pnlGridSizeLayout.setVerticalGroup(
            pnlGridSizeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGridSizeLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(sldArenaSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblSize)
                .addGap(202, 202, 202))
        );

        javax.swing.GroupLayout pnlRobotManagerLayout = new javax.swing.GroupLayout(pnlRobotManager);
        pnlRobotManager.setLayout(pnlRobotManagerLayout);
        pnlRobotManagerLayout.setHorizontalGroup(
            pnlRobotManagerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(pnlGridSize, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlRobotManagerLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlRobotManagerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(scrRobotManager, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
                    .addGroup(pnlRobotManagerLayout.createSequentialGroup()
                        .addComponent(btnSave)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 68, Short.MAX_VALUE)
                        .addComponent(btnAdd)
                        .addGap(11, 11, 11)
                        .addComponent(btnRemove)))
                .addContainerGap())
        );
        pnlRobotManagerLayout.setVerticalGroup(
            pnlRobotManagerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlRobotManagerLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlGridSize, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(scrRobotManager, javax.swing.GroupLayout.DEFAULT_SIZE, 163, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlRobotManagerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnSave)
                    .addComponent(btnAdd)
                    .addComponent(btnRemove)))
        );

        pnlGridOptions.setBorder(javax.swing.BorderFactory.createTitledBorder("Grid Options"));

        tblGridOptions.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"Arena Square Highlighting", new Boolean(false)},
                {"Antialiasing (May be slower)", new Boolean(true)},
                {"Dithering", new Boolean(true)}
            },
            new String [] {
                "Description", ""
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                false, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tblGridOptions.getTableHeader().setReorderingAllowed(false);
        jscrollGridOptions.setViewportView(tblGridOptions);
        tblGridOptions.getColumnModel().getColumn(1).setMinWidth(20);
        tblGridOptions.getColumnModel().getColumn(1).setPreferredWidth(0);
        tblGridOptions.getColumnModel().getColumn(1).setMaxWidth(20);

        javax.swing.GroupLayout pnlGridOptionsLayout = new javax.swing.GroupLayout(pnlGridOptions);
        pnlGridOptions.setLayout(pnlGridOptionsLayout);
        pnlGridOptionsLayout.setHorizontalGroup(
            pnlGridOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGridOptionsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jscrollGridOptions, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
                .addContainerGap())
        );
        pnlGridOptionsLayout.setVerticalGroup(
            pnlGridOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGridOptionsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jscrollGridOptions, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout pnlSetupLayout = new javax.swing.GroupLayout(pnlSetup);
        pnlSetup.setLayout(pnlSetupLayout);
        pnlSetupLayout.setHorizontalGroup(
            pnlSetupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlSetupLayout.createSequentialGroup()
                .addComponent(pnlImagery, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(6, 6, 6))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlSetupLayout.createSequentialGroup()
                .addComponent(pnlRobotManager, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlSetupLayout.createSequentialGroup()
                .addComponent(pnlGridOptions, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(pnlSetupLayout.createSequentialGroup()
                .addComponent(pnlRobotDelay, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        pnlSetupLayout.setVerticalGroup(
            pnlSetupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlSetupLayout.createSequentialGroup()
                .addComponent(pnlRobotDelay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlImagery, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlRobotManager, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(pnlGridOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jScrollSetup.setViewportView(pnlSetup);

        jTabPane.addTab("Virtual Arena Setup", jScrollSetup);

        btnResetPhysicalNodes.setText("Reset Nodes");
        btnResetPhysicalNodes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResetPhysicalNodesActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlPhysicalSettingsLayout = new javax.swing.GroupLayout(pnlPhysicalSettings);
        pnlPhysicalSettings.setLayout(pnlPhysicalSettingsLayout);
        pnlPhysicalSettingsLayout.setHorizontalGroup(
            pnlPhysicalSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalSettingsLayout.createSequentialGroup()
                .addGap(140, 140, 140)
                .addComponent(btnResetPhysicalNodes)
                .addContainerGap(105, Short.MAX_VALUE))
        );
        pnlPhysicalSettingsLayout.setVerticalGroup(
            pnlPhysicalSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlPhysicalSettingsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnResetPhysicalNodes)
                .addContainerGap(598, Short.MAX_VALUE))
        );

        jTabPane.addTab("Physical Arena Settings", pnlPhysicalSettings);

        pnlCommand.setBorder(javax.swing.BorderFactory.createTitledBorder("Command Window"));

        txtInput.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtInputActionPerformed(evt);
            }
        });
        txtInput.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtInputKeyReleased(evt);
            }
        });

        txtOutput.setColumns(20);
        txtOutput.setEditable(false);
        txtOutput.setRows(5);
        spaneOutput.setViewportView(txtOutput);

        btnCommandSubmit.setText("Submit");
        btnCommandSubmit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCommandSubmitActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlCommandLayout = new javax.swing.GroupLayout(pnlCommand);
        pnlCommand.setLayout(pnlCommandLayout);
        pnlCommandLayout.setHorizontalGroup(
            pnlCommandLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlCommandLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlCommandLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(spaneOutput, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE)
                    .addGroup(pnlCommandLayout.createSequentialGroup()
                        .addComponent(txtInput, javax.swing.GroupLayout.DEFAULT_SIZE, 264, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnCommandSubmit)))
                .addContainerGap())
        );
        pnlCommandLayout.setVerticalGroup(
            pnlCommandLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlCommandLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlCommandLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnCommandSubmit)
                    .addComponent(txtInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(spaneOutput, javax.swing.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout pnlLeftPanelLayout = new javax.swing.GroupLayout(pnlLeftPanel);
        pnlLeftPanel.setLayout(pnlLeftPanelLayout);
        pnlLeftPanelLayout.setHorizontalGroup(
            pnlLeftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlLeftPanelLayout.createSequentialGroup()
                .addGroup(pnlLeftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnlLeftPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jTabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE))
                    .addGroup(pnlLeftPanelLayout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(pnlCommand, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );
        pnlLeftPanelLayout.setVerticalGroup(
            pnlLeftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlLeftPanelLayout.createSequentialGroup()
                .addComponent(jTabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 679, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlCommand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jspSplitPane.setLeftComponent(pnlLeftPanel);

        mainToolbar.setFloatable(false);
        mainToolbar.setRollover(true);

        btnFile.setText("File");
        btnFile.setFocusable(false);
        btnFile.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnFile.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        mainToolbar.add(btnFile);

        btnAbout.setText("About");
        btnAbout.setFocusable(false);
        btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        mainToolbar.add(btnAbout);
        mainToolbar.add(jSeparator1);

        jbtID.setText("Position in queue: 0");
        mainToolbar.add(jbtID);
        jbtID.setForeground(Color.red);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 750, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addComponent(jspSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 730, Short.MAX_VALUE)
                .addGap(10, 10, 10))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(mainToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jspSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 871, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void btnLoadBehaviorPhysicalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadBehaviorPhysicalActionPerformed
        /*Object[] robots = lstPhysicalRobots.getSelectedValues();
        int[] indices = lstPhysicalRobots.getSelectedIndices();
        String strBehavior = (String) lstPhysicalBehaviors.getSelectedValue().toString();
        int bnum = lstVirtualBehaviors.getSelectedIndex();
        Behavior behavior = null;
        for (int i = 0; i < robots.length; i++) {
        behavior = bl.getBehavior(behaviorList.get(bnum).getID());
        behavior.setRobot(criep.CRIEP.PhysicalArena.robotMap.get((String) robots[i]));
        }
        if (behavior != null) {
        for (int i = 0; i < robots.length; i++) {
        criep.CRIEP.PhysicalArena.robotMap.get(robots[i]).behavior = behavior;
        updateOutput("Physical: " + robots[i] + " loaded behavior " + behavior.getID() + ".");
        ((DefaultListModel) lstPhysicalRobots.getModel()).setElementAt((String) robots[i] + " (" + behavior.getID() + " active)", indices[i]);
        }
        }*/

        Object[] robots = lstPhysicalRobots.getSelectedValues();
        int[] indices = lstPhysicalRobots.getSelectedIndices();
        for (int i = 0; i < robots.length; i++) {
            String r = ((String) robots[i]).split(" ")[0];
            robots[i] = (Object) r;
        }
        String strBehavior = (String) lstPhysicalBehaviors.getSelectedValue().toString();
        int bnum = lstPhysicalBehaviors.getSelectedIndex();
        Behavior behavior = null;
        if (strBehavior != null) {
            for (int i = 0; i < robots.length; i++) {
                behavior = bl.getBehavior(behaviorList.get(bnum).getID());
                behavior.setRobot(criep.CRIEP.PhysicalArena.robotMap.get((String) robots[i]));
                criep.CRIEP.PhysicalArena.robotMap.get(robots[i]).behavior = behavior;
                ((DefaultListModel) lstPhysicalRobots.getModel()).setElementAt((String) robots[i] + " (" + behavior.getID() + " active)", indices[i]);
                criep.CRIEP.PhysicalArena.robotMap.get((String) robots[i]).behavior = behavior;
                updateOutput("Physical: " + robots[i] + " loaded behavior " + behavior.getID() + ".");
            }
        }

}//GEN-LAST:event_btnLoadBehaviorPhysicalActionPerformed

    private void btnLoadBehaviorVirtualActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadBehaviorVirtualActionPerformed
        Object[] robots = lstVirtualRobots.getSelectedValues();
        int[] indices = lstVirtualRobots.getSelectedIndices();
        for (int i = 0; i < robots.length; i++) {
            String r = ((String) robots[i]).split(" ")[0];
            robots[i] = (Object) r;
        }
        String strBehavior = (String) lstVirtualBehaviors.getSelectedValue().toString();
        int bnum = lstVirtualBehaviors.getSelectedIndex();
        Behavior behavior = null;
        if (strBehavior != null) {
            for (int i = 0; i < robots.length; i++) {
                behavior = bl.getBehavior(behaviorList.get(bnum).getID());
                behavior.setRobot(criep.CRIEP.VirtualArena.robotMap.get((String) robots[i]));
                ((DefaultListModel) lstVirtualRobots.getModel()).setElementAt((String) robots[i] + " (" + behavior.getID() + " active)", indices[i]);
                criep.CRIEP.VirtualArena.robotMap.get((String) robots[i]).behavior = behavior;
                updateOutput("Virtual: " + robots[i] + " loaded behavior " + behavior.getID() + ".");
            }
        }
}//GEN-LAST:event_btnLoadBehaviorVirtualActionPerformed

    private void sldRobotDelayStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldRobotDelayStateChanged
        if (sldRobotDelay.getValueIsAdjusting()) {
            robotDelay = sldRobotDelay.getValue();
            ((TitledBorder) pnlRobotDelay.getBorder()).setTitle("Robot Movement Delay (" + robotDelay + " ms)");
            pnlRobotDelay.repaint();
        }
}//GEN-LAST:event_sldRobotDelayStateChanged

    private void btnResetNodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnResetNodeActionPerformed
        nodePatternLoaded = false;
        lblNodePattern.setText("Node Pattern Not Loaded");
        virtualWidth = sldArenaSize.getValue();
        virtualHeight = sldArenaSize.getValue();
        sldArenaSize.setEnabled(true);
}//GEN-LAST:event_btnResetNodeActionPerformed

    private void btnLoadPatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadPatternActionPerformed
        fc.addChoosableFileFilter(new MyFilter());
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == fc.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            if (file != null) {
                nodePatternFile = file.getAbsolutePath();
                Dimension d = img.getDimension(nodePatternFile);
                criep.CRIEP.VirtualArena = img.populateArena(nodePatternFile);
                lblNodePattern.setText(file.getName() + " Loaded Successfully!");
                nodePatternLoaded = true;
                virtualWidth = d.width;
                virtualHeight = d.width;
                sldArenaSize.setEnabled(false);
            }
        }
}//GEN-LAST:event_btnLoadPatternActionPerformed

    private void tblRobotManagerKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tblRobotManagerKeyPressed
}//GEN-LAST:event_tblRobotManagerKeyPressed

    private void tblRobotManagerKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tblRobotManagerKeyTyped
}//GEN-LAST:event_tblRobotManagerKeyTyped

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
        if (tblRobotManager.getRowCount() == 0) {
            ((DefaultTableModel) tblRobotManager.getModel()).addRow(new Object[]{(String) "Robot1", null, null});
        } else {
            int largest = 0;
            for (int i = 0; i < tblRobotManager.getRowCount(); i++) {
                int check = Integer.parseInt(((String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(i, 0)).substring(5));
                if (check > largest) {
                    largest = check;
                }
            }
            boolean exists;
            for (int j = 1; j <= largest + 1; j++) {
                exists = false;
                for (int i = 0; i < tblRobotManager.getRowCount(); i++) {
                    int check = Integer.parseInt(((String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(i, 0)).substring(5));
                    if (check == j) {
                        exists = true;
                        break;
                    }
                }
                if (exists == false) {
                    ((DefaultTableModel) tblRobotManager.getModel()).addRow(new Object[]{(String) "Robot" + (j), null, null});
                    sortRobotTable();
                    break;
                }
            }
        }

}//GEN-LAST:event_btnAddActionPerformed

    public void sortRobotTable() {
        ArrayList<String> robotList = new ArrayList<String>();
        ArrayList<Object[]> values = new ArrayList<Object[]>();
        for (int i = 0; i < tblRobotManager.getRowCount(); i++) {
            robotList.add((String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(i, 0));
        }
        java.util.Collections.sort(robotList);

        for (int i = 0; i < robotList.size(); i++) {
            for (int j = 0; j < tblRobotManager.getRowCount(); j++) {
                if (((String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(j, 0)).equals(robotList.get(i))) {
                    Object[] list = new Object[]{robotList.get(i),
                        ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(j, 1),
                        ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(j, 2),
                        ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(j, 3)};
                    values.add(list);
                    break;
                }
            }
        }
        while (tblRobotManager.getRowCount() > 0) {
            ((DefaultTableModel) tblRobotManager.getModel()).removeRow(0);
        }
        for (int k = 0; k < values.size(); k++) {
            ((DefaultTableModel) tblRobotManager.getModel()).addRow(values.get(k));
        }
    }
    private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveActionPerformed

        int[] selected = tblRobotManager.getSelectedRows();
        if (selected.length != 0) {
            String robotList[] = new String[selected.length];
            for (int i = 0; i < selected.length; i++) {
                robotList[i] = (String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(selected[i], 0);
            }

            for (int i = 0; i < tblRobotManager.getRowCount(); i++) {
                String robot = ((String) ((DefaultTableModel) tblRobotManager.getModel()).getValueAt(i, 0));
                for (int j = 0; j < selected.length; j++) {
                    if (robot.equals(robotList[j])) {
                        ((DefaultTableModel) tblRobotManager.getModel()).removeRow(i);
                        i--;
                    }
                }
            }
            sortRobotTable();
        }
}//GEN-LAST:event_btnRemoveActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed

        Iterator<Robot> rit = criep.CRIEP.VirtualArena.robotMap.values().iterator();
        while (rit.hasNext()) {
            ((VirtualRobot) rit.next()).cancel();
        }
        groupMap.clear();
        if (!nodePatternLoaded) {
            criep.CRIEP.VirtualArena = new Arena(virtualWidth, virtualHeight);
        }
        DefaultTableModel model = (DefaultTableModel) tblRobotManager.getModel();
        int x;
        int y;
        for (int i = 0; i < model.getRowCount(); i++) {
            try {
                x = (Integer) model.getValueAt(i, 1);
                y = (Integer) model.getValueAt(i, 2);
                if (x > -1 && x < virtualWidth && y > -1 && y < virtualHeight) {

                    VirtualRobot robot = new VirtualRobot((String) model.getValueAt(i, 0),
                            new Point((Integer) model.getValueAt(i, 1), (Integer) model.getValueAt(i, 2)),
                            ((String) model.getValueAt(i, 3)).toCharArray()[0]);
                    criep.CRIEP.VirtualArena.robotMap.put((String) model.getValueAt(i, 0), robot);
                }
            } catch (Exception ex) {
                updateOutput("Could not add " + model.getValueAt(i, 0) + " to grid.");
                continue;
            }
        }
        DefaultListModel robotList = new DefaultListModel();
        Iterator<String> it = criep.CRIEP.VirtualArena.robotMap.keySet().iterator();
        int i = 0;
        robotList.clear();
        while (it.hasNext()) {
            String robotID = it.next();
            robotList.add(i, robotID);
            i++;
        }
        lstVirtualRobots.setModel(robotList);
}//GEN-LAST:event_btnSaveActionPerformed

    private void sldArenaSizeMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sldArenaSizeMouseReleased
}//GEN-LAST:event_sldArenaSizeMouseReleased

    private void sldArenaSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldArenaSizeStateChanged
        virtualWidth = sldArenaSize.getValue();
        virtualHeight = sldArenaSize.getValue();
        lblSize.setText("Current Size: " + virtualWidth + "x" + virtualHeight);
}//GEN-LAST:event_sldArenaSizeStateChanged

    private void sldArenaSizePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_sldArenaSizePropertyChange
}//GEN-LAST:event_sldArenaSizePropertyChange

    private void btnCommandSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCommandSubmitActionPerformed

        int index = jTabPane.getSelectedIndex();
        Robot robot = null;
        String command = null;
        String[] commands;
        commands = txtInput.getText().split(" ");
        try {
            if (index == 0) { //Physical
                if (QueueClient.position == 1) {
                    robot = criep.CRIEP.PhysicalArena.robotMap.get("R" + commands[0].substring(1).toLowerCase());
                    if (robot != null && robot.behavior != null) {
                        command = commands[1];
                        updateOutput("Physical: " + robot.getID() + " moving to " + command);
                        robot.move(command);
                    }
                } else {
                    updateOutput("You do not have control of the physical robots");
                }
            } else if (index == 1) { //Virtual
                if (commands[0].equalsIgnoreCase("swarm")) {
                    updateOutput("Swarm is moving to (" + commands[1] + ")");
                    for (int i = 1; i <= criep.CRIEP.VirtualArena.robotMap.size(); i++) {
                        robot = criep.CRIEP.VirtualArena.robotMap.get("Robot" + i);
                        if (robot.behavior != null && robot.behavior.getID().equals("Particle Swarm Optimization")) {
                            try {
                                robot.move(commands[1]);
                                Thread.sleep(10);
                            } catch (InterruptedException ex) {
                            }
                        }
                    }
                } else if (commands[0].equalsIgnoreCase("creategroup")) {
                    if (commands.length == 3) {
                        createGroup(commands[1], commands[2]);
                    }
                } else if (commands[0].equalsIgnoreCase("delgroup")) {
                    if (commands.length == 2 && groupMap.containsKey(commands[1])) {
                        groupMap.remove(commands[1]);
                        updateOutput("Group: " + commands[1] + " has been deleted.");
                    }
                } else if (commands[0].equalsIgnoreCase("group")) {
                    if (commands.length == 3 && groupMap.containsKey(commands[1])) {
                        ArrayList lst = groupMap.get(commands[1].toLowerCase());
                        updateOutput("Group: " + commands[1] + " is moving to (" + commands[2] + ")");
                        for (int i = 0; i < lst.size(); i++) {
                            robot = (Robot) lst.get(i);
                            if (robot != null && robot.behavior != null) {
                                try {
                                    robot.move(commands[2]);
                                    Thread.sleep(500);
                                } catch (InterruptedException ex) {
                                }
                            }
                        }
                    }
                } else {
                    robot = criep.CRIEP.VirtualArena.robotMap.get("R" + commands[0].substring(1).toLowerCase());
                    if (robot != null && robot.behavior != null) {
                        command = commands[1];
                        updateOutput("Virtual: " + robot.getID() + " moving to " + command);
                        robot.move(command);
                    }
                }
            }
        } catch (Exception ex) {
            updateOutput("Command not recognized.");
        }
        txtInput.setText("");
}//GEN-LAST:event_btnCommandSubmitActionPerformed

    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
        DatabaseConnect dbConnect = new DatabaseConnect();
        btnConnect.setEnabled(false);
        new Thread(dbConnect).start();
        if (!QueueClient.run) {
            queueClient = new QueueClient();
            new Thread(queueClient).start();
        }
        if (!VideoThread.run) {
            VideoThread videoThread = new VideoThread(Main.videoPane);
            new Thread(videoThread).start();
        }
    }//GEN-LAST:event_btnConnectActionPerformed

    private void txtInputKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtInputKeyReleased
        if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) {
            btnCommandSubmitActionPerformed(null);
        }
    }//GEN-LAST:event_txtInputKeyReleased

    private void txtInputActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtInputActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtInputActionPerformed

    private void btnResetPhysicalNodesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnResetPhysicalNodesActionPerformed
        Set<String> keys = criep.CRIEP.PhysicalArena.robotMap.keySet();
        Iterator<String> iter = keys.iterator();

        while (iter.hasNext()) {
            Robot robot = criep.CRIEP.PhysicalArena.robotMap.get(iter.next());
            Behavior behavior = bl.getBehavior(behaviorList.get(1).getID());

            behavior.setRobot(robot);
            robot.behavior = behavior;

            new RobotManager(robot, behavior).start();
        }
    }//GEN-LAST:event_btnResetPhysicalNodesActionPerformed

    class RobotManager extends Thread {

        Robot robot;
        Behavior behavior;
        private volatile boolean running = true;

        RobotManager(Robot robot, Behavior behavior) {
            this.robot = robot;
            this.behavior = behavior;
            robot.move(robot.getInitialLocation().toString());
        }

        public void end() {
            running = false;
        }

        @Override
        public void run() {
            while (running) {
                if (robot.getLocation().toString().equals(robot.getInitialLocation().toString())) {

                    behavior.setRobot(null);
                    robot.behavior = null;

                    criep.CRIEP.PhysicalArena.reset();
                    this.end();
                    this.interrupt();
                }
            }
        }
    }
    private void txtUsernameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtUsernameActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtUsernameActionPerformed

    private void btnRefreshVirtualListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshVirtualListActionPerformed
        refreshVirtualList();
    }//GEN-LAST:event_btnRefreshVirtualListActionPerformed

    private void btnRefreshPhysicalListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshPhysicalListActionPerformed
        refreshPhysicalList();
    }//GEN-LAST:event_btnRefreshPhysicalListActionPerformed

    /**
     * Runnable class used to connect to the database in a thread
     */
    class DatabaseConnect implements Runnable {

        public void run() {
            DBComm.connect();
            criep.CRIEP.getRobotsFromDB();
            btnConnect.setEnabled(true);
        }
    }

    /**
     * Refresh list of behaviors using the BehaviorLoader
     */
    public void refreshVirtualList() {
        DefaultListModel dl = new DefaultListModel();
        behaviorList = bl.getClasses();
        for (int i = 0; i < behaviorList.size(); i++) {
            dl.add(i, behaviorList.get(i).getID());
            updateOutput("Virtual: dynamically loaded " + behaviorList.get(i).getID());
        }
        lstVirtualBehaviors.setModel(dl);
    }

    /**
     * Refresh list of behaviors using the BehaviorLoader
     */
    public void refreshPhysicalList() {
        DefaultListModel dl = new DefaultListModel();
        behaviorList = bl.getClasses();
        for (int i = 0; i < behaviorList.size(); i++) {
            dl.add(i, behaviorList.get(i).getID());
            updateOutput("Physical: dynamically loaded " + behaviorList.get(i).getID());
        }
        lstPhysicalBehaviors.setModel(dl);
    }

    /**
     * Class that filters files and only accepts images
     * @author Gabriel Loewen
     */
    class MyFilter extends javax.swing.filechooser.FileFilter {

        public boolean accept(File file) {
            String filename = file.getName();
            return filename.endsWith(".png") || filename.endsWith(".jpg") ||
                    filename.endsWith(".gif");
        }

        public String getDescription() {
            return "Image";
        }
    }

    /**
     * Creates a group of robots.
     * @param name      The name of the group
     * @param values    A comma separated list of robots
     * @return          True if the group was created without error
     */
    public boolean createGroup(String name, String values) {

        String[] sRobots;
        ArrayList<Robot> robots = new ArrayList<Robot>();
        if (values.startsWith("{") && values.endsWith("}")) {
            sRobots = values.substring(1, values.length() - 1).split(",");
            for (int i = 0; i < sRobots.length; i++) {
                robots.add(criep.CRIEP.VirtualArena.robotMap.get("R" + sRobots[i].toLowerCase().substring(1)));
            }
            groupMap.put(name.toLowerCase(), robots);
            txtOutput.append("Group: " + name.toLowerCase() + " created with robots " + values + "\n");
        } else {
            return false;
        }

        return true;

    }

    /**
     * Updates the output window with new text
     * @param text   Text to be sent to the output
     */
    public static void updateOutput(String text) {
        txtOutput.append(text + "\n");
        txtOutput.setCaretPosition(txtOutput.getText().length());
        spaneOutput.getVerticalScrollBar().setValue(spaneOutput.getVerticalScrollBar().getValue() + txtOutput.getLineCount() * 2);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAbout;
    private javax.swing.JButton btnAdd;
    public static javax.swing.JButton btnCommandSubmit;
    private javax.swing.JButton btnConnect;
    private javax.swing.JButton btnFile;
    private javax.swing.JButton btnLoadBehaviorPhysical;
    private javax.swing.JButton btnLoadBehaviorVirtual;
    private javax.swing.JButton btnLoadPattern;
    private javax.swing.JButton btnRefreshPhysicalList;
    private javax.swing.JButton btnRefreshVirtualList;
    private javax.swing.JButton btnRemove;
    private javax.swing.JButton btnResetNode;
    private javax.swing.JButton btnResetPhysicalNodes;
    private javax.swing.JButton btnSave;
    private javax.swing.JScrollPane jScrollPhysical;
    private javax.swing.JScrollPane jScrollSetup;
    private javax.swing.JScrollPane jScrollVirtual;
    private javax.swing.JToolBar.Separator jSeparator1;
    public javax.swing.JTabbedPane jTabPane;
    public static javax.swing.JLabel jbtID;
    private javax.swing.JScrollPane jscrollGridOptions;
    public javax.swing.JSplitPane jspSplitPane;
    private javax.swing.JLabel lblAddress;
    private javax.swing.JLabel lblDatabase;
    private javax.swing.JLabel lblNodePattern;
    private javax.swing.JLabel lblPassword;
    private javax.swing.JLabel lblSize;
    private javax.swing.JLabel lblUsername;
    private javax.swing.JList lstPhysicalBehaviors;
    public static javax.swing.JList lstPhysicalRobots;
    public javax.swing.JList lstVirtualBehaviors;
    public javax.swing.JList lstVirtualRobots;
    private javax.swing.JToolBar mainToolbar;
    private javax.swing.JPanel pnlCommand;
    private javax.swing.JPanel pnlDatabase;
    private javax.swing.JPanel pnlGridOptions;
    private javax.swing.JPanel pnlGridSize;
    private javax.swing.JPanel pnlImagery;
    private javax.swing.JPanel pnlLeftPanel;
    private javax.swing.JPanel pnlPhysical;
    private javax.swing.JPanel pnlPhysicalBehaviors;
    private javax.swing.JPanel pnlPhysicalRobotList;
    private javax.swing.JPanel pnlPhysicalSettings;
    private javax.swing.JPanel pnlRobotDelay;
    private javax.swing.JPanel pnlRobotManager;
    private javax.swing.JPanel pnlSetup;
    private javax.swing.JPanel pnlVirtual;
    private javax.swing.JPanel pnlVirtualBehaviors;
    private javax.swing.JPanel pnlVirtualRobotList;
    private javax.swing.JScrollPane scrRobotManager;
    private javax.swing.JSlider sldArenaSize;
    private javax.swing.JSlider sldRobotDelay;
    private static javax.swing.JScrollPane spaneOutput;
    private javax.swing.JScrollPane spanePhysicalBehaviors;
    private javax.swing.JScrollPane spanePhysicalRobotList;
    private javax.swing.JScrollPane spaneVirtualBehaviors;
    private javax.swing.JScrollPane spaneVirtualRobotList;
    private javax.swing.JToolBar tbarPhysical;
    private javax.swing.JToolBar tbarVirtual;
    public static javax.swing.JTable tblGridOptions;
    private javax.swing.JTable tblRobotManager;
    public static javax.swing.JTextField txtAddress;
    public static javax.swing.JTextField txtDatabase;
    private javax.swing.JTextField txtInput;
    public static javax.swing.JTextArea txtOutput;
    public static javax.swing.JPasswordField txtPassword;
    public static javax.swing.JTextField txtUsername;
    // End of variables declaration//GEN-END:variables
}
